import groovyx.net.http.HTTPBuilder
import static groovyx.net.http.Method.GET
import static groovyx.net.http.Method.POST
import static groovyx.net.http.ContentType.TEXT
import static groovyx.net.http.ContentType.HTML

/**
 * 네이트 기사 본문 내용을 파싱하고 저장하는 클래스
 * 
 * @author : TaeHo Kim (xissysnd@gmail.com)
 */
class Article {
	String title
	String url
	String articleId
	String content
	String thumbnailLink
	String imageLink
	String media
	Date dateCreated
	Date dateModified
	Date dateViewed = new Date()
	static hasMany = [listOfBeple : Reply]
	
    static constraints = {
		title(blank:false)
		content(blank:false)
		url(url:true)
		articleId(blank:false)
    }
	
	static mapping = {
		// dateCreated가 자동으로 갱신되는 것을 방지한다.
		autoTimestamp false
		
		content type: "text"
	}
	
	String toString() {
		title
	}
	
	
	/**
	 * 지정된 URL의 기사 본문을 파싱
	 * <p>
	 * tagsoup + XmlSlurper로 인자로 들어온 뉴스 기사 페이지 URL의 내용을 파싱한다.
	 * 기사 제목, 이미지URL, 본문, 출처, 전송시간, 수정시간 등. 
	 * 기사 컨텐츠의 br태그는 '\r\n'으로 바꾸고
	 * 출력될 필요가 없는 script태그는 없앤다.
	 * 
	 * @param articleLinkUrl 네이트 뉴스 기사 페이지 URL
	 * @return 해당 URL 기사를 파싱하여 저장한 Article 인스턴스
	 */
	 static def parseArticle(String articleLinkUrl) {
		def url = new URL(articleLinkUrl)
    	def articleReader = new HTTPBuilder(url.getProtocol() + '://' + url.getHost()).request(GET,TEXT) { 
    		uri.path = url.getPath()
		}
        assert articleReader instanceof Reader // response data is buffered in-memory
        
		def slurper = new XmlSlurper(new org.ccil.cowan.tagsoup.Parser())
        
    	def html = slurper.parse(articleReader)
		def isSportsSection = false
		def article = html.body.'**'.find{ it.name() == 'div' && it.@id == 'articleView' }
		if (article == null) {
			isSportsSection = true
			article = html.body.'**'.find{ it.name() == 'div' && it.@id == 'cntArea' }
		}
    	
		def info = article.p.find{ it.@class == 'articleInfo' }

    	def dateCreated = new Date()
    	def dateModified = new Date()
		try {
			dateCreated = Date.parse('yyyy-MM-dd hh:mm', info.span.find{it.@class == 'firstDate'}.em.text())
		} catch(java.text.ParseException e) {}
		try {
			dateModified = Date.parse('yyyy-MM-dd hh:mm', info.span.find{it.@class == 'lastDate'}.em.text())
		} catch(java.text.ParseException e) {}
		
		def contentNode = article.div.find{ it.@id == 'articleContetns' }.table.tr.td
		if (isSportsSection) {
			contentNode = article.'**'.find{ it.name() == 'div' && it.@id == 'articleContetns' }
		}

		contentNode.'**'.findAll{ it.name() == 'br' }.each{ br -> br.replaceBody('<BR />') }
		contentNode.'**'.findAll{ it.name() == 'script' }.each { script -> script.replaceBody('') }
		contentNode.'**'.findAll{ it.name() == 'img' }.each{ img -> 
			img.replaceBody("<div class='thumbnailImage'><img src='${img.@src.text().replace('orgImg', 'thumb100')}' origImageLinkUrl='${img.@src.text()}' /></div>") 
		}
		
		def parsedArticle = new Article()
		parsedArticle.title = article.h3
		// 사진은 있는 기사도 있고 없는 기사도 있음
		parsedArticle.imageLink = ''
		parsedArticle.thumbnailLink = ''
		try {
			parsedArticle.imageLink = contentNode.'**'.find{ it.name() == 'img' }.@src
			parsedArticle.thumbnailLink = parsedArticle.imageLink.replace('orgImg', 'thumb100')
		} catch(Exception) {}
		parsedArticle.content = contentNode.text().trim()
		parsedArticle.url = articleLinkUrl
		parsedArticle.articleId = url.getPath().replace('/view/', '')
		parsedArticle.media = info.span.a[0]
		parsedArticle.dateCreated = dateCreated
		parsedArticle.dateModified = dateModified
		parsedArticle.listOfBeple = []
		
		return parsedArticle
	}
	
}
